package com.biyesheji.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.biyesheji.common.BaseContext;
import com.biyesheji.common.R;
import com.biyesheji.domain.*;
import com.biyesheji.dto.WaresDto;
import com.biyesheji.service.*;
import com.biyesheji.utils.MapDistance1;
import com.biyesheji.utils.ValidateCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 员工信息 前端控制器
 * </p>
 *
 * @author 崔
 * @since 2023-02-12
 */
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IEmployeeService employeeService;

    @Autowired
    private IWaresService waresService;

    @Autowired
    private IOrdersService ordersService;

    @Autowired
    IBusinessService businessService;

    @Autowired
    IUserService userService;


    /*
     *    发送手机短信验证码
     * */
    @PostMapping("/sendMsg")
    public R<String> sendMsg(@RequestBody Employee employee, HttpSession session) {

        System.out.println("发短信运行了！！");

        // 获取手机号
        String phone = employee.getPhone();

        if (StringUtils.isNotEmpty(phone)) {

            // 生成随机的4位验证码
            String code = ValidateCodeUtils.generateValidateCode(4).toString();

            // 模拟手机短信验证码发送，在控制台看输出结果，得到验证码
            log.info("code={}", code);

             /*调用阿里云提供的短信服务 API 完成发送短信,因为在阿里云注册短信麻烦,需要企业营业等的质料，
             目前未达到要求，所以用日志输出模拟以下就好，下面就是发送短信验证码的代码，需要配合阿里云的短信服务*/
//            SMSUtils.sendMessage("短信签名","短信模板code", phone, code);

            // 需要将生成的验证码保存到 Session
//            session.setAttribute(phone, code);

            // 将生成的验证码缓存到 Redis 中, 并且设置有效期为 5 分钟
            redisTemplate.opsForValue().set("employee_" + phone, code, 5, TimeUnit.MINUTES);


//            return R.success("短信发送成功,小花的验证码为： " + code);
            return R.success("短信发送成功,你的验证码为： " + code);
        }

        return R.error("短信发送失败");
    }


    /*
     *    移动端用户登录
     * */
    @PostMapping("/login")
    public R<Employee> login(@RequestBody Map map, HttpSession session) {
        log.info(map.toString());

        //  获取手机号
        String phone = map.get("phone").toString();

        // 获取验证码
        String code = map.get("code").toString();

        // 获取密码
        String password = map.get("password").toString();

        // 从 Session 中获取保存的验证码
//        Object codeInSession = session.getAttribute(phone);


        // 从 Redis 中获取缓存的验证码
        Object codeInSession = redisTemplate.opsForValue().get("employee_" + phone);


        // 进行验证码的比对(页面提交的验证码和 Session 中保存的验证码比对)
        if (codeInSession != null && codeInSession.equals(code)) {
            // 如果能够比对成功，说明登录成功

            System.out.println("phone 的数据是:  " +phone);
            LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Employee::getPhone, phone);

            Employee employee = employeeService.getOne(queryWrapper);

            System.out.println("employee 的数据是:  " +employee);

            if (employee == null) {
                // 判断当前手机号对应的用户是否为新用户，如果是新用户就自动完成注册
/*                employee = new Employee();
                employee.setPhone(phone);
                employee.setStatus(1);
                employeeService.save(employee);  */
                return R.error("该员工不存在");

            } else {

                //  1、 将页面提交的密码 password 进行 md5 加密处理
                password = DigestUtils.md5DigestAsHex(password.getBytes());

                //  4、 密码比对，如果不一致则返回登录失败结果
                if (!employee.getPassword().equals(password)) {
                    return R.error("密码错误，登录失败");
                }

                //  5、 查看员工状态，如果为已禁用状态，则返回员工已禁用结果
                if (employee.getStatus() == 0) {
                    return R.error("该账号已禁用");
                }
            }

            session.setAttribute("employee", employee.getId());

            // 如果用户登录成功, 删除 Redis 中缓存的验证码
            redisTemplate.delete(phone);

            return R.success(employee);
        }

        return R.error("登录失败");
    }


    /*
     *    员工退出
     * */
    @GetMapping("/loginout")
    public R<String> loginout(HttpServletRequest request){

        // 清理 Session 中保存的当前登录商家的 id
        request.getSession().removeAttribute("employee");

        System.out.println("退出登录运行了");

        return R.success("退出成功");
    }




    /*
     *     查询商品民宿信息
     * */
    @GetMapping("/getWares")
    public R<List> getWares(String location, String waresId, String Range, String phone, Integer status) {


        List<WaresDto> waresDtos = new ArrayList<>();

        System.out.println(" location 得到的数据是：  " + location);
        System.out.println(" waresName 得到的数据是：  " + waresId);
        System.out.println(" Range 得到的数据是：  " + Range);
        System.out.println(" phone 得到的数据是：  " + phone);
        System.out.println(" status 得到的数据是：  " + status);
        if (status == 4) {
            status = null;
        }


        if (location != null && location != "") {
            // 将字符串截取成 经度 和 纬度
            String[] split = location.split(",");
            System.out.println();
            System.out.println(split[1]);

            // 获取范围(四个最大和最小的经纬度封装到 map 集合中)
            Map around = MapDistance1.getAround(split[0], split[1], Range + "000");

            // 根据输入的条件得到民宿 Wares 的集合
            List<Wares> wares = waresService.getWares(Long.valueOf(waresId), null, (String) around.get("maxLng"), (String) around.get("minLng"), (String) around.get("maxLat"), (String) around.get("minLat"), null, Long.valueOf(phone), status);


            for (int i = 0; i < wares.size(); i++) {

                WaresDto waresDto = new WaresDto();
                Wares wares1 = wares.get(i);

                // 将 wares1 的同名同类型的数据复制到 waresDto 中
                BeanUtils.copyProperties(wares1, waresDto);

                // 计算 wares1 与前端发送的经纬度的距离
                String distance = MapDistance1.getDistance(split[0], split[1], wares1.getAddressX(), wares1.getAddressY());

                // 对数据距离的处理，将 km 转为 m , 再舍去后面的小数
                Double aDouble = Double.valueOf(distance) * 1000;
                int i1 = aDouble.intValue();
                int i2 = Integer.valueOf(Range);


                //  经纬度的位置再范围内才加入 List 集合
                if (i1 <= (i2 * 1000)) {
                    waresDto.setImage("/common/download?name=" + waresDto.getImage());
                    waresDto.setAddressDistance(i1 + "");
                    waresDtos.add(waresDto);
                }

            }
        } else {

            List<Wares> wares = waresService.getWares(Long.valueOf(waresId), null, null, null, null, null, null, Long.valueOf(phone), status);
            for (int i = 0; i < wares.size(); i++) {

                WaresDto waresDto = new WaresDto();
                Wares wares1 = wares.get(i);

                // 将 wares1 的同名同类型的数据复制到 waresDto 中
                BeanUtils.copyProperties(wares1, waresDto);
                waresDto.setAddressDistance("");
                waresDto.setImage("/common/download?name=" + waresDto.getImage());
                waresDtos.add(waresDto);
            }
        }
        return R.success(waresDtos);
    }




    /*
     *     修改订单状态为 0
     *     员工启用和禁用民宿
     *
     * */
    @PutMapping("/updateWares")
    public R<String> updateWares(@RequestBody Wares wares) throws ParseException {

        System.out.println("wares 的数据是：   " + wares);
        Boolean aBoolean = waresService.updateWaresStatus(wares);

        return R.success("修改失败");
    }




    /*
     *     查询订单信息
     * */
    @GetMapping("/getOrders")
    public R<List> getOrders(String businessPhone, Integer status, String userPhone) throws ParseException {

        System.out.println( "id 为：  " + businessPhone + ",status 为:  " + status + ",userPhone 为:  " + userPhone);

        ordersService.initialize();


        List<Orders> list = new ArrayList<>();


        List<Business> businessList = businessService.getBusinessList(businessPhone);

        System.out.println("businessList 的数据是：  " + businessList);

        for (int i = 0; i < businessList.size(); i++) {

            Business business = businessList.get(i);

            List wares = waresService.getWaresByBusinessPhone(business.getPhone());

            if (wares != null){
                for (int j = 0; j < wares.size(); j++) {

                    Wares  wares1 = (Wares) wares.get(j);
                    List orders = ordersService.getEmployeeOrders(wares1.getId(), userPhone, status);
                    list.addAll(orders);
                }
            }

            System.out.println( "wares的数据是：  " + wares);


        }

        System.out.println("最终数据的 list：  " + list);
        return R.success(list);
    }


    /*
     *     查询用户信息
     * */
    @GetMapping("/getUsers")
    public R<List> getUsers(Integer status, String userPhone) throws ParseException {

        System.out.println( ",status 为:  " + status + ",userPhone 为:  " + userPhone);


        List<User> user = userService.getUser(null, userPhone, status);




        return R.success(user);
    }


    /*
     *     修改用户状态
     *
     * */
    @PutMapping("/updateUser")
    public R<String> updateUser(@RequestBody User user) throws ParseException {

        System.out.println("user 的数据是：   " + user);
        Boolean aBoolean = userService.updateUser(user);




        if (aBoolean){
            return R.success("修改成功");
        }

        return R.success("修改失败");
    }

    /*
     *     修改商家状态
     *
     * */
    @PutMapping("/updateBusiness")
    public R<String> updateBusinessPhone(@RequestBody Business business) throws ParseException {

        System.out.println("Business 的数据是：   " + business);
        Boolean aBoolean = businessService.updateBusiness(business);




        if (aBoolean){
            return R.success("修改成功");
        }

        return R.success("修改失败");
    }


    /*
     *     查询用户信息
     * */
    @GetMapping("/getBusiness")
    public R<List> getBusiness(Integer status, String businessPhone) throws ParseException {

        System.out.println( ",status 为:  " + status + ",businessPhone 为:  " + businessPhone);


        List<Business> businessList = businessService.getBusiness(null, businessPhone, status);




        return R.success(businessList);
    }


    /*
     *     查询用户信息
     * */
    @GetMapping("/getEmployee")
    public R<List> getEmployee(Integer status, String phone) throws ParseException {

        System.out.println( "status 为:  " + status + ",phone 为:  " + phone);


        List<Employee> list = new ArrayList<>();

        List<Employee> employeeList = employeeService.getEmployeeList(phone, status);

//        List<Business> businessList = businessService.getBusiness(null, business, status);




        return R.success(employeeList);
    }



    /*
     *     修改员工状态
     *
     * */
    @PutMapping("/updateEmployee")
    public R<String> updateEmployee(@RequestBody Employee employee) throws ParseException {

        System.out.println("Business 的数据是：   " + employee);

        boolean b = employeeService.updateById(employee);


        if (b){
            return R.success("修改成功");
        }

        return R.success("修改失败");
    }







    /*
     *     申请商品
     *
     * */
    @PostMapping("/saveEmployee")
    public R<String> saveEmployee(@RequestBody Employee employee) throws ParseException {

        System.out.println("employee 的数据是：   " + employee);


        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());
        employee.setPassword(DigestUtils.md5DigestAsHex(employee.getPassword().getBytes()));

        System.out.println("employee 的数据是：   " + employee);

        boolean b = employeeService.save(employee);


        if (b){
            return R.success("保存成功");
        }

        return R.success("保存失败");
    }



    /*
     *     员工修改密码
     * */
    @PostMapping("/changPassword")
    public R<String> changPassword(@RequestBody Map map){
        log.info(map.toString());

        //  获取手机号
        String phone = map.get("phone").toString();

        // 获取验证码
        String code = map.get("code").toString();

        // 获取密码
        String password = map.get("password").toString();

        // 获取密码
        String newPassword = map.get("newPassword").toString();


        // 从 Session 中获取保存的验证码
//        Object codeInSession = session.getAttribute(phone);


        // 从 Redis 中获取缓存的验证码
        Object codeInSession = redisTemplate.opsForValue().get("employee_"+phone);



        // 进行验证码的比对(页面提交的验证码和 Session 中保存的验证码比对)
        if (codeInSession != null && codeInSession.equals(code)) {
            // 如果能够比对成功，说明登录成功

            LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Employee::getPhone, phone);

            Employee employee = employeeService.getOne(queryWrapper);


            if (employee == null) {
                // 判断当前手机号对应的用户是否为新用户，如果是新用户就自动完成注册
/*                business = new business();
                business.setPhone(phone);
                business.setStatus(1);
                businessService.save(business);  */
                return R.error("该员工不存在");

            } else {

                //  1、 将页面提交的密码 password 进行 md5 加密处理
                password = DigestUtils.md5DigestAsHex(password.getBytes());

                //  4、 密码比对，如果不一致则返回登录失败结果
                if (!employee.getPassword().equals(password)){
                    return  R.error("密码错误，修改失败");
                }

                //  5、 查看商家状态，如果为已禁用状态，则返回员工已禁用结果
                if (employee.getStatus() == 0) {
                    return R.error("该账号已禁用");
                }

                // 新密码加密
                newPassword = DigestUtils.md5DigestAsHex(newPassword.getBytes());

                employee.setPassword(newPassword);

                boolean b = employeeService.updateById(employee);

                if (b){
                    // 如果用户登录成功, 删除 Redis 中缓存的验证码
                    redisTemplate.delete(phone);

                    return R.success("修改成功");
                }


            }


        }

        return R.error("验证码错误,修改失败");
    }






}

